package guiPackage;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileNotFoundException;
import java.security.NoSuchAlgorithmException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;

import javax.swing.JFrame;
import javax.swing.JTextField;
import javax.swing.text.BadLocationException;

import queriePackage.MySqlQueries;
import databasePackage.DatabaseConnectionController;
import databasePackage.MySqlDatabase;
import fieldTypePackage.DateField;
import fieldTypePackage.DateTimeField;
import fieldTypePackage.DoubleField;
import fieldTypePackage.IntField;
import fieldTypePackage.StringField;

public class GuiController {
	private JFrame frame;
	private StartScherm startView;
	private DataScherm dataView;
	private ResultatenScherm resultatenView;
	private DatabaseConnectionController dbc;
	private MySqlDatabase mdb;
	private static SimpleDateFormat dateTimeMySql = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
	private static SimpleDateFormat dateMySql = new SimpleDateFormat("yyyy-MM-dd");
	private ArrayList<String> queries;

	public GuiController() {
		frame = new MyFrame();
		showStartScherm();
	}

	public void showStartScherm() {
		startView = new StartScherm();
		frame.setContentPane(startView);
		frame.setVisible(true);
		frame.pack();
		startView.setListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				if (e.getSource() == startView.getInleesButton()) {
					String server, username, password, dbName;
					server = getText(startView.getServerField());
					username = getText(startView.getUsernameField());
					password = getText(startView.getPasswordField());
					dbName = getText(startView.getDbNameField());
//					 server = "127.0.0.1";
//					 username = "root";
//					 password = "root";
//					 dbName = "to4db";
					dbc = new DatabaseConnectionController(server, username, password, dbName);
					mdb = new MySqlDatabase(dbc);
					mdb.importDatabaseData();
					showDataScherm();
				}
			}
		});
	}

	public void showDataScherm() {
		dataView = new DataScherm(mdb.getDatabaseData(), mdb.getAantalKolommen());
		frame.setContentPane(dataView);
		frame.setVisible(true);
		frame.pack();
		// frame.setSize(200,300);
		dataView.setListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				if (e.getSource() == dataView.getMaakQueriesButton()) {
					try {
						maakQueries(dataView.getOpvulMethoden());
						showResultatenScherm();
					} catch (FileNotFoundException e1) {
						e1.printStackTrace();
					} catch (NoSuchAlgorithmException e2) {
						e2.printStackTrace();
					} catch (ParseException e3) {
						e3.printStackTrace();
					} catch (BadLocationException e4) {
						e4.printStackTrace();
					}
				}
				if (e.getSource() == dataView.getTerugButton()) {
					frame.setContentPane(startView);
					frame.setVisible(true);
					frame.pack();
				}
			}
		});
	}

	public void showResultatenScherm() throws BadLocationException {
		resultatenView = new ResultatenScherm(queries);
		frame.setContentPane(resultatenView);
		frame.setVisible(true);
		frame.pack();
		resultatenView.setListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				if (e.getSource() == resultatenView.getTerugButton()) {
					frame.setContentPane(dataView);
					frame.setVisible(true);
					frame.pack();
				}
			}
		});
	}

	public void maakQueries(OpvulMethoden[] opvulMethoden) throws FileNotFoundException,
			NoSuchAlgorithmException, ParseException {
		// Maak eerst alle benodigde invoerwaarden aan
		String huidigeTabel = "";
		ArrayList<String> tabelGegevens = new ArrayList<>();
		ArrayList<ArrayList> alleTabelGegevens = new ArrayList<ArrayList>();
		HashMap<String, JTextField> aantalRecordsFields = dataView.getAantalRecordsFields();
		HashMap<String, ArrayList<String>> kolomWaarden = new HashMap<String, ArrayList<String>>();
		// opvulMethoden bevat voor elke kolom de gegevens die nodig zijn om de
		// database data aan te maken.
		int aantalRecords = 0;
		for (OpvulMethoden oM : opvulMethoden) {
			if (huidigeTabel != oM.getTabelNaam()) {
				tabelGegevens = new ArrayList<String>();
				alleTabelGegevens.add(tabelGegevens);
				huidigeTabel = oM.getTabelNaam();
				aantalRecords = Integer.parseInt(aantalRecordsFields.get(huidigeTabel).getText());
				tabelGegevens.add(aantalRecords + "");
				tabelGegevens.add(huidigeTabel);
			}
			tabelGegevens.add(oM.getKolomNaam());
			if (getInvoerWaarden(oM, aantalRecords) != null) {
				kolomWaarden.put(huidigeTabel + "-" + oM.getKolomNaam(),
						getInvoerWaarden(oM, aantalRecords));
			}
		}

		// Nu er invoerwaarden zijn, kunnen de queries gemaakt worden
		MySqlQueries mySqlQueries = new MySqlQueries(alleTabelGegevens, kolomWaarden);
		queries = mySqlQueries.getQueries();
	}

	public ArrayList<String> getInvoerWaarden(OpvulMethoden opvulMethode, int aantalRecords)
			throws FileNotFoundException, ParseException, NoSuchAlgorithmException {
		String selectedNaam = opvulMethode.getSelectedNaam();

		if (aantalRecords <= 0) {
			return null;
		}

		else if (opvulMethode.getKolomType().equals("INT")) {
			IntField iF = new IntField(aantalRecords);
			if (selectedNaam.equals("random int")) {
				int min = Integer.parseInt(opvulMethode.getArgs()[0].getText());
				int max = Integer.parseInt(opvulMethode.getArgs()[1].getText());
				return intGetallenNaarString(iF.maakRandomLijst(min, max));
			}
			if (selectedNaam.equals("oplopend int")) {
				int min = Integer.parseInt(opvulMethode.getArgs()[0].getText());
				return intGetallenNaarString(iF.maakOplopendLijst(min));
			}
		}

		else if (opvulMethode.getKolomType().equals("DECIMAL")) {
			DoubleField dF = new DoubleField(aantalRecords);
			if (selectedNaam.equals("random double")) {
				double min = Double.parseDouble(opvulMethode.getArgs()[0].getText());
				double max = Double.parseDouble(opvulMethode.getArgs()[1].getText());
				return doubleGetallenNaarString(dF.maakRandomLijst(min, max));
			}
			if (selectedNaam.equals("oplopend double")) {
				double start = Double.parseDouble(opvulMethode.getArgs()[0].getText());
				double inc = Double.parseDouble(opvulMethode.getArgs()[1].getText());
				return doubleGetallenNaarString(dF.maakOplopendLijst(start, inc));
			}
		}

		else if (opvulMethode.getKolomType().equals("DATETIME")) {
			DateTimeField dtF = new DateTimeField(aantalRecords);
			if (selectedNaam.equals("random datetime")) {
				String beginDateTimeString = opvulMethode.getArgs()[0].getText();
				String eindDateTimeString = opvulMethode.getArgs()[1].getText();
				Calendar beginDateTime = Calendar.getInstance();
				Calendar eindDateTime = Calendar.getInstance();
				beginDateTime.setTime(dateTimeMySql.parse(beginDateTimeString));
				eindDateTime.setTime(dateTimeMySql.parse(eindDateTimeString));
				int minUur = Integer.parseInt(opvulMethode.getArgs()[2].getText());
				int maxUur = Integer.parseInt(opvulMethode.getArgs()[3].getText());
				return dateTimeNaarStringMySql(dtF.maakRandomLijst(beginDateTime, eindDateTime,
						minUur, maxUur));
			}
		}

		else if (opvulMethode.getKolomType().equals("DATE")) {
			DateField daF = new DateField(aantalRecords);
			if (selectedNaam.equals("random date")) {
				String beginDateTimeString = opvulMethode.getArgs()[0].getText();
				String eindDateTimeString = opvulMethode.getArgs()[1].getText();
				Calendar beginDateTime = Calendar.getInstance();
				Calendar eindDateTime = Calendar.getInstance();
				beginDateTime.setTime(dateMySql.parse(beginDateTimeString));
				eindDateTime.setTime(dateMySql.parse(eindDateTimeString));
				return dateTimeNaarStringMySql(daF.maakRandomLijst(beginDateTime, eindDateTime));
			}
		}

		else if (opvulMethode.getKolomType().equals("VARCHAR")) {
			StringField sF = new StringField(aantalRecords);
			if (selectedNaam.equals("voornaam")) {
				return sF.importVoorNamen();
			}
			if (selectedNaam.equals("achternaam")) {
				return sF.importAchterNamen();
			}
			if (selectedNaam.equals("plaatsnaam")) {
				return sF.importPlaatsNamen();
			}
			if (selectedNaam.equals("straatnaam")) {
				return sF.importStraatNamen();
			}
			if (selectedNaam.equals("huisnummer")) {
				return sF.maakHuisNummers();
			}
			if (selectedNaam.equals("adres")) {
				return sF.maakAdressen();
			}
			if (selectedNaam.equals("postcode")) {
				return sF.maakPostcodes();
			}
			if (selectedNaam.equals("email")) {
				return sF.maakEmailAdress();
			}
			if (selectedNaam.equals("gebruikersnaam")) {
				return sF.getGebruikersNamen();
			}
			if (selectedNaam.equals("wachtwoord")) {
				return sF.getWachtwoorden();
			}
			if (selectedNaam.equals("telnr")) {
				return sF.maakTelefoonNummers();
			}
			if (selectedNaam.equals("bestand")) {
				File opgegevenBestand = new File(opvulMethode.getArgs()[0].getText());
				return sF.importOpgegevenBestand(opgegevenBestand);
			}
			if (selectedNaam.equals("nummer")) {
				int aantalCijfers = Integer.parseInt(opvulMethode.getArgs()[0].getText());
				int min = Integer.parseInt(opvulMethode.getArgs()[1].getText());
				int max = Integer.parseInt(opvulMethode.getArgs()[2].getText());
				return sF.maakNummerLijst(aantalCijfers, min, max);
			}
		}
		return null;
	}

	public ArrayList<String> dateTimeNaarStringMySql(ArrayList<Calendar> datumLijst) {
		ArrayList<String> stringLijst = new ArrayList<String>();
		for (Calendar c : datumLijst) {
			stringLijst.add(dateTimeMySql.format(c.getTime()));
		}
		return stringLijst;
	}
	
	public ArrayList<String> dateNaarStringMySql(ArrayList<Calendar> datumLijst) {
		ArrayList<String> stringLijst = new ArrayList<String>();
		for (Calendar c : datumLijst) {
			stringLijst.add(dateMySql.format(c.getTime()));
		}
		return stringLijst;
	}

	public ArrayList<String> intGetallenNaarString(ArrayList<Integer> getallenLijst) {
		ArrayList<String> stringLijst = new ArrayList<String>();
		for (int i : getallenLijst) {
			stringLijst.add(i + "");
		}
		return stringLijst;
	}

	public ArrayList<String> doubleGetallenNaarString(ArrayList<Double> getallenLijst) {
		ArrayList<String> stringLijst = new ArrayList<String>();
		for (double d : getallenLijst) {
			stringLijst.add(d + "");
		}
		return stringLijst;
	}

	public String getText(JTextField tf) {
		if (tf == null) {
			throw new IllegalArgumentException("Textfield mag niet null zijn!");
		}
		String text = tf.getText();
		if (text == null || text.trim().equals("")) {
			throw new IllegalArgumentException("Geen text in textfield!");
		}
		return text;
	}
}
